package proccrontrol

import (
	"communication-system/client/modelc"
	"communication-system/common/messages"
	"communication-system/common/utils"
	"communication-system/server/model"
	"encoding/json"
	"fmt"
	"net"
)

type UserProcess struct {
}

//Login()处理client侧登录相关的主要逻辑
func (userprocess *UserProcess) Login(uid int, pwd string) (err error) {
	fmt.Println("")
	//启动一个客户端连接服务器
	fmt.Println("--------客户端建立与服务器端的通信连接--------")
	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("net.Dial与服务器端建立连接失败,err=", err)
		return
	}
	defer conn.Close()
	fmt.Println("--------客户端开始封装需要发送的消息体--------")
	//准备要要送到服务端的消息
	var mess messages.Message
	//确定要发送的消息类型是登录消息类型
	mess.Type = messages.LoginMessType
	//准备Data，由于Message中得Data是string,所以需要对LoginMess进行进行序列化
	var loginMess messages.LoginMess
	loginMess.UserId = uid
	loginMess.UserPwd = pwd
	data, err := json.Marshal(loginMess)
	if err != nil {
		fmt.Println("loginMess序列化失败,err=", err)
		return
	}
	// fmt.Println("序列化之后的data:", data)
	mess.Data = string(data)
	//对mess进行序列化，网络之间传输都是通过json之类的
	mdata, err := json.Marshal(mess)
	if err != nil {
		fmt.Println("mess序列化失败,err=", err)
		return
	}

	fmt.Println("--------客户端封装需要发送的消息体完毕--------")
	fmt.Println("--------客户端发送消息体到服务端开始--------")
	//发送数据到服务端
	transfer := &utils.TransFer{
		Conn: conn,
	}
	//调用发送数据函数
	err = transfer.WritePkg(mdata)
	if err != nil {
		fmt.Println("客户端发送数据失败...,err=", err)
		return
	}
	fmt.Println("--------客户端发送消息体到服务端完毕--------")
	fmt.Println("----------以下为客户端接收服务端在校验登录信息之后返回的结果----------")
	//读取服务端返回的消息
	fmt.Println("--------客户端接收服务器端返回消息开始--------")
	resmes, err := transfer.Readpkg()
	if err != nil {
		fmt.Println("客户端接收返回数据失败...,err=", err)
		return
	}
	// fmt.Printf("resmes.Data的类型:%T,值:%v\n", resmes.Data, resmes)
	fmt.Println("--------客户端接收服务器端返回消息结束--------")
	//将返回的resmes反序列化成结构体进行处理
	var Lresmes messages.LoginResMess
	err = json.Unmarshal([]byte(resmes.Data), &Lresmes)
	if err != nil {
		fmt.Println("客户端接收返回数据反序列化失败...,err=", err)
		return
	}
	if Lresmes.Code == 200 {
		fmt.Println("登录成功")
		//初始化发消息的curUser

		modelc.Curuser.Conn = conn
		modelc.Curuser.UserId = uid
		modelc.Curuser.UserStatus = messages.UserOnline

		//登录成功后，遍历在线的用户id
		fmt.Println("登录成功后返回的用户信息:", Lresmes.UserIds)
		for _, v := range Lresmes.UserIds {
			// fmt.Printf("当前在线的用户id=%d\n", v)
			if v == uid { //不打印自己的id,只打印好友的
				continue
			}
			//完成客户端onlineUsers的初始化
			user := &model.User{
				UserId:     v,
				UserStatus: messages.UserOnline,
			}
			onlineUsers[v] = user
		}
		fmt.Println("")

		//此处需要另外启动一个协程专门一直去读取服务端的消息，只要有消息过来就打印在客户端
		go serverProcessMes(conn)

		//登录成功后显示的菜单栏，一直提示
		for {
			show_menu()
		}
	} else {
		fmt.Println(Lresmes.Error)
	}

	return
}

//Register()处理client侧注册相关的主要逻辑
func (userprocess *UserProcess) Register(uid int, pwd string, name string) (err error) {
	fmt.Println("")
	//启动一个客户端连接服务器
	fmt.Println("--------客户端建立与服务器端的通信连接--------")
	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("net.Dial与服务器端建立连接失败,err=", err)
		return
	}
	defer conn.Close()
	fmt.Println("--------客户端开始封装需要发送的注册消息体--------")
	//准备要要送到服务端的消息
	var Registermess messages.Message
	//确定要发送的消息类型是登录消息类型
	Registermess.Type = messages.RegisterMessType
	//准备Data，由于Message中得Data是string,所以需要对Registermess进行进行序列化
	var RegisterMess messages.LoginMess
	RegisterMess.UserId = uid
	RegisterMess.UserPwd = pwd
	RegisterMess.UserName = name
	data, err := json.Marshal(RegisterMess)
	if err != nil {
		fmt.Println("loginMess序列化失败,err=", err)
		return
	}
	// fmt.Println("序列化之后的data:", data)
	Registermess.Data = string(data)
	//对mess进行序列化，网络之间传输都是通过json之类的
	mdata, err := json.Marshal(Registermess)
	if err != nil {
		fmt.Println("mess序列化失败,err=", err)
		return
	}

	fmt.Println("--------客户端封装需要发送的消息体完毕--------")
	fmt.Println("--------客户端发送消息体到服务端开始--------")
	//发送数据到服务端
	transfer := &utils.TransFer{
		Conn: conn,
	}
	//调用发送数据函数
	err = transfer.WritePkg(mdata)
	if err != nil {
		fmt.Println("客户端发送数据失败...,err=", err)
		return
	}
	fmt.Println("--------客户端发送消息体到服务端完毕--------")
	fmt.Println("----------以下为客户端接收服务端在校验登录信息之后返回的结果----------")
	//读取服务端返回的消息
	fmt.Println("--------客户端接收服务器端返回消息开始--------")
	resmes, err := transfer.Readpkg()
	if err != nil {
		fmt.Println("客户端接收返回数据失败...,err=", err)
		return
	}
	// fmt.Printf("resmes.Data的类型:%T,值:%v\n", resmes.Data, resmes)
	fmt.Println("--------客户端接收服务器端返回消息结束--------")
	//将返回的resmes反序列化成结构体进行处理
	var Rresmes messages.RegisterResMess
	err = json.Unmarshal([]byte(resmes.Data), &Rresmes)
	if err != nil {
		fmt.Println("客户端接收返回数据反序列化失败...,err=", err)
		return
	}
	if Rresmes.Code == 200 {
		fmt.Println("注册成功,请重新登录")

	} else {
		fmt.Println(Rresmes.Error)
	}

	return
}
